package com.weilele.mvvm.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.viewbinding.ViewBinding
import com.weilele.mvvm.utils.activity.toast
import com.weilele.mvvm.utils.printStackTrace
import com.weilele.mvvm.utils.safeGet
import java.lang.IllegalArgumentException
import java.lang.reflect.ParameterizedType


/**
 * 通过viewHolder类创建ViewHolder对象
 */
fun <Holder : MvvmHolder<*, *>> Class<Holder>.createHolderInstance(
    inflater: LayoutInflater,
    parent: ViewGroup? = null,
    attach: Boolean = false,
): Holder {
    val bindingCls = this.getParameterizedType()
        ?.actualTypeArguments?.get(1)
        ?.safeGet<Class<ViewBinding>>()
    val binding = bindingCls
        ?.createViewBindingInstance(inflater, parent, attach)
        ?: throw IllegalArgumentException("通过viewHolder类（${this.name}）创建ViewHolder对象失败")
    return this.getConstructor(bindingCls).newInstance(binding) as Holder
}

/**
 * 将class转为ParameterizedType，方便获取此类的类泛型
 */
fun Class<*>?.getParameterizedType(): ParameterizedType? {
    if (this == null) {
        return null
    }
    val type = this.genericSuperclass
    return if (type == null || type !is ParameterizedType) {
        this.superclass.getParameterizedType()
    } else {
        type
    }
}


/**
 * 通过binding类反射创建binding对象
 */
fun <Binding : ViewBinding?> Class<Binding>.createViewBindingInstance(
    inflater: LayoutInflater,
    parent: ViewGroup? = null,
    attach: Boolean = false,
): Binding? {
    return ignoreError {
        this.getMethod(
            "inflate",
            LayoutInflater::class.java,
            ViewGroup::class.java,
            Boolean::class.java
        ).invoke(null, inflater, parent, attach) as? Binding?
    }
}

/**
 * 忽略错误,默认不提示异常
 */
inline fun <T> ignoreError(isToast: Boolean = false, call: () -> T?): T? {
    return try {
        call.invoke()
    } catch (e: Throwable) {
        printStackTrace { e }
        if (isToast) {
            e.message.toast()
        }
        null
    }
}
